package com.dom.springcore;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

import static com.dom.springcore.HandleBeansInfo.activebeansMaps;
import static com.dom.springcore.HandleBeansInfo.beansInfoMaps;

public class SpringCore {

    public static Object getBean(String name) {
        BeanInfo beanInfo = beansInfoMaps.get(name);
        if (beanInfo == null) {
            return null;
        }
        Object object = activebeansMaps.get(name);
        if (object != null) {
            if (beanInfo.getScope().equals("single"))
                return object;
            Object temp = createObject(beanInfo);
            HandleBeansInfo.activebeansMaps.replace(name, temp);
            return temp;
        }
        Object temp = createObject(beanInfo);
        HandleBeansInfo.activebeansMaps.put(name, temp);
        return temp;
    }

    private static Object createObject(BeanInfo beanInfo) {
        String className = beanInfo.getClassName();
        Object object = null;
        try {
            Class<?> clz = Class.forName(className);
            object = clz.getDeclaredConstructor().newInstance();
            List<String> propertiesName = beanInfo.getProperties();
            if (propertiesName == null) {
                return object;
            }
            for (int i = 0; i < propertiesName.size(); i++) {
                String fieldName = propertiesName.get(i);
                //获取字节码世界中的属性对象
                Field field = null;
                try {
                    field = clz.getDeclaredField(fieldName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (field == null) continue;
                field.setAccessible(true);

                String value = beanInfo.getValues().get(i);
                if(value.contains("ref:")) {
                    Object bean = getBean(value.substring(4));
                    field.set(object,bean);
                } else {
                    if(field.getType()==Integer.class||field.getType()==Integer.TYPE)
                        field.set(object, Integer.parseInt(value));
                    else if(field.getType()==Double.class||field.getType()==Double.TYPE)
                        field.set(object, Double.parseDouble(value));
                    else if(field.getType()==Float.class||field.getType()==Float.TYPE)
                        field.set(object, Float.parseFloat(value));
                    else if(field.getType()==Boolean.class||field.getType()==Boolean.TYPE)
                        field.set(object, Boolean.parseBoolean(value));
                    else
                        field.set(object, value);
                }

            }

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        return object;
    }

}
